import axios from 'axios';
import { isRefreshToken, refreshTokenApi } from '@/api/auth';
import router from '@/router';

// 创建axios实例
const request = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL,
    timeout: 60000,
});

// 状态码常量
const STATUS = {
    SUCCESS: 200,
    TOKEN_EXPIRED: 108,
};

// 用于存储等待重试的请求队列
let isRefreshing = false;
let failedQueue = [];
let refreshPromise = null;

// 处理队列中的请求
const processQueue = (error, token = null) => {
    failedQueue.forEach(({ resolve, reject }) => {
        if (error) {
            reject(error);
        } else {
            resolve(token);
        }
    });

    failedQueue = [];
};

// 清除token和刷新状态
const clearTokens = () => {
    localStorage.removeItem('token');
    localStorage.removeItem('refresh_token');
    isRefreshing = false;
    refreshPromise = null;
    failedQueue = [];
};

// 安全的路由跳转到登录页，并记录当前路径
const safeRouterPushToLogin = () => {
    console.log('safeRouterPushToLogin');
    try {
        const currentPath = router.currentRoute.value.fullPath;

        // 如果当前已经在登录页，不需要跳转
        if (currentPath === '/login') {
            return;
        }

        // 记录当前路径，用于登录成功后跳转回来
        const redirectPath = currentPath !== '/' ? currentPath : '';

        // 检查当前URL中是否已经包含重定向参数，避免重复记录
        const currentQuery = new URLSearchParams(window.location.search);
        if (currentQuery.has('redirect')) {
            router.push('/login');
            return;
        }

        if (redirectPath) {
            router.push({
                path: '/login',
                query: { redirect: redirectPath }
            });
        } else {
            router.push('/login');
        }
    } catch (error) {
        console.error('路由跳转失败:', error);
        // 如果路由跳转失败，尝试直接跳转
        const currentPath = window.location.pathname + window.location.search;
        const currentQuery = new URLSearchParams(window.location.search);
        const redirectParam = currentPath !== '/' && currentPath !== '/login' && !currentQuery.has('redirect')
            ? `?redirect=${encodeURIComponent(currentPath)}`
            : '';
        window.location.href = `/login${redirectParam}`;
    }
};

// 刷新token的核心逻辑
const refreshTokenAndRetry = async () => {
    try {
        const res = await refreshTokenApi();

        if (res && res.access_token) {
            localStorage.setItem('token', res.access_token);
            localStorage.setItem('refresh_token', res.refresh_token);
            return res.access_token;
        }
        throw new Error('刷新token响应格式错误');
    } catch (error) {
        clearTokens();
        safeRouterPushToLogin();
        throw error;
    }
};

// 请求拦截器
request.interceptors.request.use(
    config => {
        const token = localStorage.getItem('token');
        // 非刷新token请求且token存在时添加token
        if (token && !isRefreshToken(config)) {
            config.headers['Authorization'] = `Bearer ${token}`;
        }
        return config;
    },
    error => {
        console.error('请求发送失败:', error);
        return Promise.reject({
            code: 500,
            message: '请求发送失败'
        });
    }
);

// 响应拦截器
request.interceptors.response.use(
    // 成功响应处理
    response => {
        const { data } = response;

        // 如果响应有code字段，按业务逻辑处理
        if (data && typeof data.code !== 'undefined') {
            if (data.code === STATUS.SUCCESS) {
                return data;
            } else {
                // 业务错误
                return Promise.reject({
                    code: data.code,
                    message: data.message || '请求失败',
                    data: data.data
                });
            }
        }

        // 没有code字段的响应直接返回
        return data || response;
    },
    // 错误响应处理
    async error => {
        // 网络错误或请求被取消
        if (!error.response) {
            return Promise.reject({
                code: 500,
                message: '网络错误，请检查您的网络连接'
            });
        }

        const { response, config: originalRequest } = error;
        const responseData = response.data || {};
        const errorCode = responseData.code || response.status;

        // 处理token过期
        if (errorCode === STATUS.TOKEN_EXPIRED) {
            // 如果当前请求已经是刷新token的请求，直接登出
            if (isRefreshToken(originalRequest)) {
                clearTokens();
                safeRouterPushToLogin();
                return Promise.reject({
                    code: 108,
                    message: '登录已过期，请重新登录'
                });
            }

            // 将请求加入队列
            if (!isRefreshing) {
                isRefreshing = true;
                refreshPromise = refreshTokenAndRetry()
                    .then(token => {
                        processQueue(null, token);
                        return token;
                    })
                    .catch(error => {
                        processQueue(error, null);
                        throw error;
                    })
                    .finally(() => {
                        isRefreshing = false;
                        refreshPromise = null;
                    });
            }

            // 返回一个新的Promise，等待刷新token完成
            return new Promise((resolve, reject) => {
                failedQueue.push({
                    resolve: token => {
                        originalRequest.headers['Authorization'] = `Bearer ${token}`;
                        resolve(request(originalRequest));
                    },
                    reject: error => {
                        reject(error);
                    }
                });
            }).catch(error => {
                // 确保错误对象格式一致
                return Promise.reject({
                    code: error.code || 401,
                    message: error.message || '登录已过期，请重新登录'
                });
            });
        }

        // 其他错误情况
        return Promise.reject({
            code: errorCode,
            message: responseData.message || '请求失败，请稍后重试',
            data: responseData.data
        });
    }
);

export default request;